package com.sci.web.util;



import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.Arrays;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.sci.config.MyConstants;


public class ImageUtil {
	    private static Logger log = MyConstants.log;
	    
	    private static String DEFAULT_THUMB_PREVFIX = "thumb_";
	    private static String DEFAULT_CUT_PREVFIX = "cut_";
	    private static Boolean DEFAULT_FORCE = false;
	    
	    
	    /**
	     * <p>Title: cutImage</p>
	     * <p>Description:  根据原图与裁切size截取局部图片</p>
	     * @param srcImg    源图片
	     * @param output    图片输出流
	     * @param rect        需要截取部分的坐标和大小
	     */
	    public static void cutImage(File srcImg, OutputStream output, java.awt.Rectangle rect){
	        if(srcImg.exists()){
	            java.io.FileInputStream fis = null;
	            ImageInputStream iis = null;
	            try {
	                fis = new FileInputStream(srcImg);
	                // ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
	                String types = Arrays.toString(ImageIO.getReaderFormatNames()).replace("]", ",");
	                String suffix = null;
	                // 获取图片后缀
	                if(srcImg.getName().indexOf(".") > -1) {
	                    suffix = srcImg.getName().substring(srcImg.getName().lastIndexOf(".") + 1);
	                }// 类型和图片后缀全部小写，然后判断后缀是否合法
	                if(suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase()+",") < 0){
	                    log.error("Sorry, the image suffix is illegal. the standard image suffix is {}." + types);
	                    return ;
	                }
	                // 将FileInputStream 转换为ImageInputStream
	                iis = ImageIO.createImageInputStream(fis);
	                // 根据图片类型获取该种类型的ImageReader
	                ImageReader reader = ImageIO.getImageReadersBySuffix(suffix).next();
	                reader.setInput(iis,true);
	                ImageReadParam param = reader.getDefaultReadParam();
	                param.setSourceRegion(rect);
	                BufferedImage bi = reader.read(0, param);
	                ImageIO.write(bi, suffix, output);
	            } catch (FileNotFoundException e) {
	                e.printStackTrace();
	            } catch (IOException e) {
	                e.printStackTrace();
	            } finally {
	                try {
	                    if(fis != null) fis.close();
	                    if(iis != null) iis.close();
	                } catch (IOException e) {
	                    e.printStackTrace();
	                }
	            }
	        }else {
	            log.warn("the src image is not exist.");
	        }
	    }
	    
	    public static void cutImage(File srcImg, OutputStream output, int x, int y, int width, int height){
	        cutImage(srcImg, output, new java.awt.Rectangle(x, y, width, height));
	    }
	    
	    public static String cutImage(File srcImg, String destImgPath, java.awt.Rectangle rect){
	        File destImg = new File(destImgPath);
	        if(destImg.exists()){
	            String p = destImg.getPath();
	            try {
	                if(!destImg.isDirectory()) p = destImg.getParent();
	                if(!p.endsWith(File.separator)) p = p + File.separator;
	                String realName = p + DEFAULT_CUT_PREVFIX + "_" + new java.util.Date().getTime() + "_" + srcImg.getName();
	                cutImage(srcImg, new java.io.FileOutputStream(realName), rect);
	                return realName;
	            } catch (FileNotFoundException e) {
	                log.warn("the dest image is not exist.");
	            }
	        }else log.warn("the dest image folder is not exist.");
	        return null;
	    }
	    
	    public static String cutImage(File srcImg, String destImg, int x, int y, int width, int height){
	        return cutImage(srcImg, destImg, new java.awt.Rectangle(x, y, width, height));
	    }
	    
	    public static String cutImage(String srcImg, String destImg, int x, int y, int width, int height){
	       return  cutImage(new File(srcImg), destImg, new java.awt.Rectangle(x, y, width, height));
	    }
	    /**
	     * <p>Title: thumbnailImage</p>
	     * <p>Description: 根据图片路径生成缩略图 </p>
	     * @param imagePath    原图片路径
	     * @param w            缩略图宽
	     * @param h            缩略图高
	     * @param prevfix    生成缩略图的前缀
	     * @param force        是否强制按照宽高生成缩略图(如果为false，则生成最佳比例缩略图)
	     */
	    public static void thumbnailImage(File srcImg, OutputStream output, int w, int h, String prevfix, boolean force){
	        if(srcImg.exists()){
	            try {
	                // ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
	                String types = Arrays.toString(ImageIO.getReaderFormatNames()).replace("]", ",");
	                String suffix = null;
	                // 获取图片后缀
	                if(srcImg.getName().indexOf(".") > -1) {
	                    suffix = srcImg.getName().substring(srcImg.getName().lastIndexOf(".") + 1);
	                }// 类型和图片后缀全部小写，然后判断后缀是否合法
	                if(suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase()+",") < 0){
	                    log.error("Sorry, the image suffix is illegal. the standard image suffix is {}." + types);
	                    return ;
	                }
	                log.debug("target image's size, width:{}, height:{}.");
	                Image img = ImageIO.read(srcImg);
	                // 根据原图与要求的缩略图比例，找到最合适的缩略图比例
	                if(!force){
	                    int width = img.getWidth(null);
	                    int height = img.getHeight(null);
	                    if((width*1.0)/w < (height*1.0)/h){
	                        if(width > w){
	                            h = Integer.parseInt(new java.text.DecimalFormat("0").format(height * w/(width*1.0)));
	                            log.debug("change image's height, width:{}, height:{}.");
	                        }
	                    } else {
	                        if(height > h){
	                            w = Integer.parseInt(new java.text.DecimalFormat("0").format(width * h/(height*1.0)));
	                            log.debug("change image's width, width:{}, height:{}.");
	                        }
	                    }
	                }
	                BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
	                Graphics g = bi.getGraphics();
	                g.drawImage(img, 0, 0, w, h, Color.LIGHT_GRAY, null);
	                g.dispose();
	                // 将图片保存在原目录并加上前缀
	                ImageIO.write(bi, suffix, output);
	                output.close();
	            } catch (IOException e) {
	               log.error("generate thumbnail image failed.",e);
	            }
	        }else{
	            log.warn("the src image is not exist.");
	        }
	    }
	    public static void thumbnailImage(File srcImg, int w, int h, String prevfix, boolean force){
	        String p = srcImg.getAbsolutePath();
	        try {
	            if(!srcImg.isDirectory()) p = srcImg.getParent();
	            if(!p.endsWith(File.separator)) p = p + File.separator;
	            thumbnailImage(srcImg, new java.io.FileOutputStream(p + prevfix +srcImg.getName()), w, h, prevfix, force);
	        } catch (FileNotFoundException e) {
	            log.error("the dest image is not exist.",e);
	        }
	    }
	    
	    public static void thumbnailImage(String imagePath, int w, int h, String prevfix, boolean force){
	        File srcImg = new File(imagePath);
	        thumbnailImage(srcImg, w, h, prevfix, force);
	    }
	    
	    public static void thumbnailImage(String imagePath, int w, int h, boolean force){
	        thumbnailImage(imagePath, w, h, DEFAULT_THUMB_PREVFIX, DEFAULT_FORCE);
	    }
	    
	    public static void thumbnailImage(String imagePath, int w, int h){
	        thumbnailImage(imagePath, w, h, DEFAULT_FORCE);
	    }
	    
	    /**  
	    * @Title: zoomImageScale  
	    * @Description: 清晰度较高
	    * @param sourceFile
	    * @param newWidth
	    * @param newHeight
	    * @throws IOException      
	    * @returnType void      
	    * @author LiuFei
	    * @date 下午4:22:35
	    * @throws  
	    */
	    public static  void zoomImageScale(String sourceFile , String newPath,  int newWidth , int newHeight) throws IOException {
	        
	    	
	    	
	    	File imageFile = new File(sourceFile);
	    	if(!imageFile.canRead())
	             return;
	        BufferedImage bufferedImage = ImageIO.read(imageFile);
	        if (null == bufferedImage) 
	            return;
	        
	        int originalWidth = bufferedImage.getWidth();
	        int originalHeight = bufferedImage.getHeight();
	       
	        
	        double scale = (double)originalWidth / (double)newWidth;    // 缩放的比例
	        
	        zoomImageUtils(imageFile, newPath, bufferedImage, newWidth, newHeight);
	    }
	    
	    
	    
	    private static void zoomImageUtils(File imageFile, String newPath, BufferedImage bufferedImage, int width, int height)
	            throws IOException{
	        
	         String suffix = StringUtils.substringAfterLast(imageFile.getName(), ".");
	        
	         // 处理 png 背景变黑的问题
	        if(suffix != null && (suffix.trim().toLowerCase().endsWith("png") || suffix.trim().toLowerCase().endsWith("gif"))){
	            BufferedImage to= new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
	            Graphics2D g2d = to.createGraphics(); 
	            to = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT); 
	            g2d.dispose(); 
	            
	            g2d = to.createGraphics(); 
	            Image from = bufferedImage.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING); 
	            g2d.drawImage(from, 0, 0, null);
	            g2d.dispose(); 
	            
	            ImageIO.write(to, suffix, new File(newPath));
	        }else{
	            // 高质量压缩，其实对清晰度而言没有太多的帮助
//	            BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//	            tag.getGraphics().drawImage(bufferedImage, 0, 0, width, height, null);
	//
//	            FileOutputStream out = new FileOutputStream(newPath);    // 将图片写入 newPath
//	            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
//	            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);
//	            jep.setQuality(1f, true);    //压缩质量, 1 是最高值
//	            encoder.encode(tag, jep);
//	            out.close();
	            
	            BufferedImage newImage = new BufferedImage(width, height, bufferedImage.getType());
	            Graphics g = newImage.getGraphics();
	            g.drawImage(bufferedImage, 0, 0, width, height, null);
	            g.dispose();
	            ImageIO.write(newImage, suffix, new File(newPath));
	        }
	    }
	    
	    
	    
	    
	    
	    
	    
	    public static void main(String[] args) throws IOException {
	        ImageUtil imageUtil = new ImageUtil();
			//imageUtil.thumbnailImage("H:/pic/2.png", 207, 300);
			
	       // new ImageUtil().cutImage("imgs/Tulips.jpg","imgs", 250, 70, 300, 400);
	        
	        File file = new File("H:/pic/000.jpg");
	        
	        BufferedImage bufferedImage = ImageIO.read(file);
	        if (null == bufferedImage) 
	            return;
	        
	        int originalWidth = bufferedImage.getWidth();
	        int originalHeight = bufferedImage.getHeight();
	        
	        int originalWidthHalf = originalWidth/2;
	        int originalHeightHalf = originalHeight/2;
	        
	        
	        int newWidth = 0;
	        int newHeight = 0;
	        
	        
	        
	        
	        if(originalWidth<originalHeight){
	        	newWidth = originalWidth;
	        	newHeight =new BigDecimal((double)originalWidth/0.875).setScale(0, BigDecimal.ROUND_HALF_UP).intValue()  ;
	        }else{
	        	newWidth = new BigDecimal((double)originalHeight*0.875).setScale(0, BigDecimal.ROUND_HALF_UP).intValue() ;
	        	newHeight = originalHeight;
	        }
	        
	        int newWidthHalf = newWidth/2;
	        int newHeightHalf = newHeight/2;
	        System.out.println(newWidth+"---"+newHeight);
	        
	        
	        
	        System.out.println((originalWidthHalf-newWidthHalf)+"----"+( originalHeightHalf-newHeightHalf));
	        
	        
	        
			imageUtil.cutImage(file, "H:/pic/000", originalWidthHalf-newWidthHalf, originalHeightHalf-newHeightHalf, newWidth, newHeight);
	    }
	    
	    
	    
	    
	    
	    
	    

}
